package ru.surfstudio.graduate.service;

import java.io.Serializable;
import java.net.URI;

import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriTemplate;

import ru.surfstudio.graduate.WSApplication;
import ru.surfstudio.graduate.exception.ParseException;
import ru.surfstudio.graduate.parser.Parser;
import ru.surfstudio.graduate.task.GetHttpTask;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class HttpService extends IntentService {

	private static final String TAG = "HttpService";
	
	public static final String MARK_STATUS = "STATUS";
	
	public static final String MARK_HANDLER = "HANDLER";
	
	public static final String MARK_TASK = "HTTP_TASK";
	
	public static final String MARK_RESPONSE = "RESPONSE";
	
	
	public static final int STATUS_RUNNING = 0x1;

    public static final int STATUS_ERROR = 0x2;

    public static final int STATUS_FINISHED = 0x3;
    
    private static final int RETRY = 2;
    

    public HttpService() {
		super(TAG);
	}
	
    @Override
    public void onCreate() {
        super.onCreate();
    }

	@Override
	protected void onHandleIntent(Intent intent) {
		Messenger messenger = intent.getParcelableExtra(MARK_HANDLER);
		Bundle responseData = new Bundle();
			
		try {
			responseData.putInt(MARK_STATUS, STATUS_RUNNING);
			sendMessage(messenger, responseData);
			
			GetHttpTask task = (GetHttpTask) intent.getSerializableExtra(MARK_TASK);
			Serializable response = sendRequest(task);
			
			responseData.putInt(MARK_STATUS, STATUS_FINISHED);
			responseData.putSerializable(MARK_RESPONSE, response);
			responseData.putSerializable(MARK_TASK, task);
			sendMessage(messenger, responseData);
			
		} catch (Exception e) {
			Log.e(TAG, e.getMessage(), e);
			responseData.putInt(MARK_STATUS, STATUS_ERROR);
			try {
				sendMessage(messenger, responseData);
			} catch (RemoteException e1) {
				Log.e(TAG, e1.getMessage(), e1);
			}
		}
		
	}
	
	private void sendMessage(Messenger messenger, Bundle responseData) throws RemoteException {
		if (messenger != null) {
			Message mess = new Message();
			mess.setData(responseData);
			Log.d(TAG, "send status " + responseData.getInt(MARK_STATUS));
			messenger.send(mess);
		}
	}
	
	
	private Serializable sendRequest(GetHttpTask task) throws ParseException {
		if (task == null)
			return null;
		
		WSApplication app = (WSApplication) getApplication();
		RestTemplate restTemplate = new RestTemplate(app.getClientHttpRequestFactory());
		
		UriTemplate template = new UriTemplate(task.getMethodName());
		URI uri = template.expand(task.getParams());
		int count = 0;
        while (count < RETRY) {
            count++;
            try {
            	Log.d(TAG, "send http reqest");
                String responseStr = restTemplate.getForObject(uri, String.class);
                
                Parser<?> parser = task.getParser();
                Log.d(TAG, "parse http response");
                return parser.parse(responseStr);
                
            } catch (RestClientException e) {
                if (count >= RETRY) {
                    throw e;
                }
            } catch (ParseException e) {
	            if (count >= RETRY) {
	                throw e;
	            }
	        }
        }
        throw new RestClientException("Request problem");
	}

}
